package com.anlogic.sdk.bootimage.internal.ui;

import com.anlogic.sdk.utils.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;

public class AutoCompleteProvider {
	private static final int POPUP_MINIMUM_HEIGHT = 300;

	private static final int POPUP_MINIMUM_WIDTH = 300;

	private Text text;

	private IAutoCompeletHelper autoCompleteHelper;

	private SimpleContentProposalProvider proposalProvider;

	private ControlDecoration decoration;

	private ContentProposalAdapter adapter;

	private String maxLengthString;

	public AutoCompleteProvider(Text text, IAutoCompeletHelper autoCompleteHelper) {
		hookAutoCompleteField(text, autoCompleteHelper);
	}

	public AutoCompleteProvider(Text text, final String relativeLocation) {
		IAutoCompeletHelper autoCompleteHelper = new IAutoCompeletHelper() {
			public String getRelativePath() {
				return relativeLocation;
			}
		};
		hookAutoCompleteField(text, autoCompleteHelper);
	}

	private void hookAutoCompleteField(Text text, IAutoCompeletHelper autoCompleteHelper) {
		this.text = text;
		this.autoCompleteHelper = autoCompleteHelper;
		this.proposalProvider = createContentProposalAdapter((Control) text,
				(IControlContentAdapter) new TextContentAdapter(), new String[0]);
		refreshProposals();
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				AutoCompleteProvider.this.refreshProposals();
			}
		});
	}

	private SimpleContentProposalProvider createContentProposalAdapter(Control control,
			IControlContentAdapter controlContentAdapter, String[] proposals) {
		this.decoration = new ControlDecoration(control, 16512);
		FieldDecoration proposalDecoration = FieldDecorationRegistry.getDefault()
				.getFieldDecoration("DEC_CONTENT_PROPOSAL");
		this.decoration.setImage(proposalDecoration.getImage());
		this.decoration.setDescriptionText("Content proposals are available. Use Ctrl+Space.");
		this.decoration.hide();
		SimpleContentProposalProvider proposalProvider = new SimpleContentProposalProvider(proposals);
		proposalProvider.setFiltering(true);
		this.adapter = new ContentProposalAdapter(control, controlContentAdapter,
				(IContentProposalProvider) proposalProvider, null, null);
		this.adapter.setPropagateKeys(true);
		this.adapter.setProposalAcceptanceStyle(2);
		return proposalProvider;
	}

	private String[] getPaths(String currentLocation, String relativeLocation) {
		this.maxLengthString = "";
		Path path = new Path(currentLocation);
		File[] files = null;
		List<String> paths = new ArrayList<>();
		if (path.isAbsolute()) {
			File file = new File(currentLocation);
			if (file.listFiles() != null) {
				files = file.listFiles();
			} else if (file.getParentFile() != null && file.getParentFile().listFiles() != null) {
				files = file.getParentFile().listFiles();
			}
			if (files == null)
				files = new File[0];
			byte b;
			int i;
			File[] arrayOfFile;
			for (i = (arrayOfFile = files).length, b = 0; b < i;) {
				File childFile = arrayOfFile[b];
				String childPath = childFile.getAbsolutePath();
				if (childPath.startsWith(currentLocation)) {
					paths.add(childPath);
					if (childPath.length() > this.maxLengthString.length())
						this.maxLengthString = childPath;
				}
				b++;
			}
		} else if (StringUtils.isNotEmpty(relativeLocation)) {
			IPath resolvedPath = (new Path(relativeLocation)).append(currentLocation);
			File file = resolvedPath.toFile();
			String prefixPath = currentLocation;
			if (file.isDirectory()) {
				files = file.listFiles();
			} else if (file.getParentFile() != null && file.getParentFile().exists()) {
				files = file.getParentFile().listFiles();
				prefixPath = path.removeLastSegments(1).toOSString();
			}
			if (files == null)
				files = new File[0];
			byte b;
			int i;
			File[] arrayOfFile;
			for (i = (arrayOfFile = files).length, b = 0; b < i;) {
				File childFile = arrayOfFile[b];
				if (StringUtils.isNotEmpty(prefixPath) && !prefixPath.endsWith(File.separator))
					prefixPath = String.valueOf(prefixPath) + File.separator;
				String childRelativeLoc = String.valueOf(prefixPath) + childFile.getName();
				IPath childResolvedPath = (new Path(relativeLocation)).append(childRelativeLoc);
				if (childResolvedPath.toFile().exists()) {
					paths.add(childRelativeLoc);
					if (childRelativeLoc.length() > this.maxLengthString.length())
						this.maxLengthString = childRelativeLoc;
				}
				b++;
			}
		}
		return paths.<String>toArray(new String[0]);
	}

	public void refreshProposals() {
		String[] proposals = getPaths(this.text.getText(), this.autoCompleteHelper.getRelativePath());
		this.proposalProvider.setProposals(proposals);
		GC gc = new GC((Drawable) this.text.getDisplay());
		Point extent = gc.stringExtent(this.maxLengthString);
		gc.dispose();
		Point popupSize = this.adapter.getPopupSize();
		if (popupSize == null)
			popupSize = new Point(POPUP_MINIMUM_WIDTH, POPUP_MINIMUM_HEIGHT);
		if (popupSize != null) {
			int x = Math.max(extent.x + 50, POPUP_MINIMUM_HEIGHT);
			int limit_x = (int) ((Display.getDefault().getBounds()).width * 0.75D);
			x = Math.min(x, limit_x);
			popupSize = new Point(x, popupSize.y);
			this.adapter.setPopupSize(popupSize);
		}
	}

	public static interface IAutoCompeletHelper {
		String getRelativePath();
	}
}
